<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button>点击</button>
  <script>
    // 1. es5函数
    // 1.1 赋值式 (匿名式)
    // fn() // 会被当做变量解析 定义函数前调用会报错
    // let fn = function(){
    //   console.log('fn');
    // }

    // 1.2 声明式
    // fn1() // 随时都能调用 不会报错
    // function fn1(){
    //   console.log('fn1');
    // }

    // 2. es6 箭头函数 简化的是赋值式的写法 声明式也会转换为赋值式

    // 箭头函数特性:
    // 2.1 形参在()里 用括号包裹 逗号隔开  如果只有一个参数 省略括号 
    // 2.2 函数体如果只有一句代码 可以省略{ } 且会隐式返还 不需要return
    // 2.3 注意 箭头函数没有arguments 如果想接收参数 用扩展运算符
    // 2.4 不能作为构造函数  
    // 2.5 箭头函数没有this绑定，它的this是上层,上下文（context）的this

    // let fn = (...args) => console.log(args)
    // fn(1, 2, 3)

    // var fn = ()=>({name:"张安",age:20});
    // console.log(fn());

    // es5:
    // var res = data.filter(function (item) {
    //   return item.age > 20
    // }).filter(function (item) {
    //   return item.gender === "女";
    // })

    // es6:
    // var data = [{ name: '小明',age: 24,gender: '男'},{name: '小芳',age: 30,gender: '女'},{name: '小美',age: 31,gender: '女'},{name: '小刚',age: 21,gender: '男'},{name: '小琪',age: 18,gender: '女'}];
    // var res = data.filter(item => item.age > 20).filter(item => item.gender === "女");
    // console.log(res);


    // 错误 会报错 箭头函数不能作为构造函数
    // var fn = (name)=>{
    //     this.name = name;
    // }
    // let zhangsan = new fn();



    // 箭头函数里的this
    // document.querySelector("button").onclick = function (){ // btn
    document.querySelector("button").onclick = () => { // 如果是箭头函数 this的指向是上一层函数作用域的this指向
      console.log(this);
      setTimeout(() => {
        console.log(this);
        var obj = {
          myname: "张三",
          fn: () => console.log(this)  // 没有this ，获取上一层的this this会穿透到上一层          
        }
        obj.fn();
      }, 0);
    }




    // 变量的赋值规则 
    function fn1 () {
      function fn2 () {
        function fn3 () {
          a = 10;  // a变量的赋值 会先找 自己作用域里的变量声明 如果有直接赋值 ，如果没有就在上层作用域查找赋值变量，一层一层向上赋值，直到赋值给全局变量；
          console.log(a);
        }
        fn3();
        console.log(a); // 10
      }
      fn2();
      console.log(a); //10
    }
    fn1();
    console.log(a); //10

    


    // 短路运算符
    function fn(cb){
      cb && cb()
    }
    // fn函数的参数是回调函数 有时可传可不传
    // 如果不传 代码是 cb()时 会报错 因为不传参数 cb是undefined 无法被调用 
    // 解决方法: 短路运算符
    fn(function(){
      console.log(1);
    })







  </script>
</body>

</html>